package service

import (
	"github.com/google/uuid"
	"golang.org/x/crypto/bcrypt"
	"guard/internal/app/admin/models"
	"guard/internal/conf"
	"guard/internal/errors"
	"guard/internal/tool"
)

func (s *adminServiceImpl) RegisterClient(username string, info *models.ClientInfo) error {
	// 用户注册最大client
	appCount, err := s.st.SelUserAppCount(username)
	if err != nil {
		return err
	}
	if appCount > conf.Conf.User.UserAppCount {
		return errors.OtherError("注册超过数量")
	}

	// 判断是否只需要更新到client-register
	if info.ClientId != "" {
		clientQuery, err := s.st.SelClientQuery(info.ClientId, info.ClientName)
		if err != nil {
			return errors.OtherError("客户端信息异常")
		}
		clientQuery.RedirectUris = info.RedirectUris
		err = s.st.UpdateClient(*info)
		if err != nil {
			return errors.OtherError("更新客户端失败")
		}
		return nil
	}

	// 写到用户app表，用于显示
	userApp := models.UserApp{}
	userApp.UserName = username
	userApp.ClientId = tool.CreateClientId()
	userApp.ClientName = info.ClientName
	userApp.ClientSecret = tool.CreateClientSecret()
	err = s.st.SaveUserApp(userApp)
	if err != nil {
		return err
	}

	// 对secret加密
	newClientSecret, err := bcrypt.GenerateFromPassword([]byte(userApp.ClientSecret), bcrypt.DefaultCost)

	// 写到oauth表
	info.Id = uuid.NewString()
	info.ClientId = userApp.ClientId
	info.ClientSecret = string(newClientSecret)
	info.AuthorizationGrantTypes = "authorization_code,refresh_token"
	info.Scopes = "userinfo"
	info.AuthorizationCodeExpires = 300
	info.AccessTokenExpires = 302400
	info.RefreshTokenExpires = 604800
	err = s.st.SaveClient(*info)
	if err != nil {
		return err
	}
	return nil
}

func (s *adminServiceImpl) UserAppAll(username string) (mu []models.UserApp, err error) {
	mu, err = s.st.SelUserApp(username)
	if err != nil {
		return mu, errors.OtherError("没有应用")
	}
	return
}

func (s *adminServiceImpl) RemoveUserApp(username, cid string) error {
	err := s.st.DelUserApp(username, cid)
	if err != nil {
		return errors.OtherError("app删除失败")
	}
	err = s.st.DelClient(cid)
	if err != nil {
		return errors.OtherError("client删除失败")
	}
	return nil
}
